package com.jyy.prefabricated.service;

import com.jyy.prefabricated.dto.StudentAchievementDto;
import com.jyy.prefabricated.dto.StudentDto;
import com.jyy.prefabricated.dto.StudentRegisterDto;
import com.jyy.prefabricated.dto.SysUserDto;
import com.jyy.prefabricated.entity.*;
import com.jyy.prefabricated.enums.BaseStatusEnum;
import com.jyy.prefabricated.enums.OrderTypeEnum;
import com.jyy.prefabricated.enums.UserTypeEnum;
import com.jyy.prefabricated.exception.CustomException;
import com.jyy.prefabricated.mapper.*;
import com.jyy.prefabricated.utils.KeyUtil;
import com.jyy.prefabricated.vo.OnlineVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @version 1.0.0
 * @author: zjj
 */
//todo 库存控制暂时注释
@Service
@Transactional
public class StudentService {

    @Resource
    private StudentExamMapper studentExamMapper;

    @Resource
    private StudentAchievementMapper studentAchievementMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private StudentProjectMapper studentProjectMapper;

    @Autowired
    private StudentCourseMapper studentCourseMapper;

    @Autowired
    private StudentCoursePackageMapper studentCoursePackageMapper;

    @Autowired
    private TrainingOrganizationStudentMapper trainingOrganizationStudentMapper;

    @Autowired
    private TrainingOrganizationStockMapper trainingOrganizationStockMapper;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private MyResourceService myResourceService;

    @Autowired
    private SmsRecordService smsRecordService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 学员注册
     *
     * @param dto
     * @return
     */
    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public Student studentRegister(StudentRegisterDto dto) {
        if (StringUtils.isBlank(dto.getIdCard())) {
            dto.setIdCard(KeyUtil.genUniqueKey());
        }

        Student checkStudent = selectByTelOrIdCard(dto.getTel(), dto.getIdCard());
        if (checkStudent != null) {
            throw new CustomException("当前手机号和身份证已注册！");
        }
        Student student = new Student();
        BeanUtils.copyProperties(dto, student);
        student.setStatus(BaseStatusEnum.VALID.getValue());
        SysUserDto user = generateUser(student);
        user.setPassword(dto.getPassword());


        if (user.getSex() == null) {
            user.setSex(1);
        }
//        //调用小鹅通注册新用户接口
//        String url = "https://api.xiaoe-tech.com/xe.user.register/1.0.0";
//        String data = "{" +
//                " \"phone\":\"" + user.getUsername() + "\"," +
//                " \"wx_name\":\"" + user.getName() + "\"," +
//                " \"gender\":" + user.getSex() +
//                "}";
//        XiaoeClient client = new XiaoeClient();
//        Map result = client.request("post", url, data);
//        System.out.println(result);
//        JSONObject jsonObject = JSONObject.parseObject(result.toString());
//        // 获取到key为shoppingCartItemList的值
//        if (jsonObject != null) {
//            String resultData = jsonObject.getString("data");
//            JSONObject jsonObjectData = JSONObject.parseObject(resultData);
//            String userId = jsonObjectData.getString("user_id");
//            user.setUserId(userId);
//            sysUserService.createUser(user);
//        }

        sysUserService.createUser(user);
        studentMapper.insert(student);
        return student;
    }

    /**
     * 新增
     *
     * @param dto
     * @return
     */
    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public int insert(StudentDto dto) {
        if (StringUtils.isBlank(dto.getIdCard())) {
            dto.setIdCard(KeyUtil.genUniqueKey());
        }
        Student student = selectByTelOrIdCard(dto.getTel(), dto.getIdCard());
        if (student == null) {
            //说明学员之前没有报名过
            student = new Student();
            BeanUtils.copyProperties(dto, student);
            student.setStatus(BaseStatusEnum.VALID.getValue());
            SysUserDto user = generateUser(student);


//            //调用小鹅通注册新用户接口
//            String url = "https://api.xiaoe-tech.com/xe.user.register/1.0.0";
//            String data = "{" +
//                    " \"phone\":\"" +user.getUsername()  + "\"," +
//                    " \"wx_name\":\"" + user.getName() + "\"," +
//                    " \"gender\":" + user.getSex() +
//                    "}";
//            XiaoeClient client = new XiaoeClient();
//            Map result = client.request("post", url, data);
//            System.out.println(result);
//            JSONObject jsonObject = JSONObject.parseObject(result.toString());
//            // 获取到key为shoppingCartItemList的值
//            String resultData= jsonObject.getString("data");
//            JSONObject jsonObjectData = JSONObject.parseObject(resultData);
//            String userId= jsonObjectData.getString("user_id");
//            user.setUserId(userId);
            sysUserService.createUser(user);
            studentMapper.insert(student);
        } else {
            //学员已经报名过了，判断是否已经在该机构注册过
            List<TrainingOrganizationStudent> trainingOrganizationStudents = trainingOrganizationStudentMapper.selectByTrainingOrganizationIdAndStudentId(dto.getTrainingOrganizationId(), student.getId());
            if (trainingOrganizationStudents.size() > 0) {
                throw new CustomException("当前学员已在机构注册！");
            }
        }
        saveStudent2TrainingOrganization(student.getId(), dto.getTrainingOrganizationId());
        saveStudentProject(dto, student.getId());
        saveStudentCourse(dto, student.getId());
        saveStudentCoursePackage(dto, student.getId());
        return student.getId();
    }


    /**
     * 新增学员（报名项目）
     *
     * @param dto
     * @return
     */
    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public int insertInfo(StudentDto dto) {
//        if (StringUtils.isBlank(dto.getIdCard())) {
//            dto.setIdCard(KeyUtil.genUniqueKey());
//        }
        Student student = selectByTelOrIdCard(dto.getTel(), dto.getIdCard());
        if (student == null) {
            //说明学员之前没有报名过
            student = new Student();
            BeanUtils.copyProperties(dto, student);
            student.setStatus(BaseStatusEnum.VALID.getValue());
            student.setTel(dto.getTel());
            SysUserDto user = generateUser(student);
            sysUserService.createUser(user);
            studentMapper.insert(student);

        } else {
            //学员已经报名过了，判断是否已经在该机构注册过
            List<TrainingOrganizationStudent> trainingOrganizationStudents = trainingOrganizationStudentMapper.selectByTrainingOrganizationIdAndStudentId(dto.getTrainingOrganizationId(), student.getId());
            if (trainingOrganizationStudents.size() > 0) {
                return student.getId();
            }
        }
        saveStudent2TrainingOrganization(student.getId(), dto.getTrainingOrganizationId());
        //saveStudentProject(dto, student.getId());

        return student.getId();
    }

    /**
     * 根据电话和身份证号校验学员是否存在
     *
     * @param tel
     * @param idCard
     * @return
     */
    public Student selectByTelOrIdCard(String tel, String idCard) {
        return studentMapper.selectByTelOrIdCard(tel, idCard);
    }


    /**
     * 绑定学员和机构间的关系
     *
     * @param studentId
     * @param trainingOrganizationId
     */
    public void saveStudent2TrainingOrganization(Integer studentId, Integer trainingOrganizationId) {
        TrainingOrganizationStudent trainingOrganizationStudent = new TrainingOrganizationStudent();
        trainingOrganizationStudent.setStudentId(studentId);
        trainingOrganizationStudent.setTrainingOrganizationId(trainingOrganizationId);
        trainingOrganizationStudentMapper.insert(trainingOrganizationStudent);
    }

    /**
     * 机构给学员分配项目
     *
     * @param dto
     * @param id
     */
    private void saveStudentProject(StudentDto dto, Integer id) {
        if (dto.getProjectIds().size() > 0) {
            List<StudentProject> studentProjects = new ArrayList<>();
            for (Integer projectId : dto.getProjectIds()) {
                TrainingOrganizationStock stock = trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(dto.getTrainingOrganizationId(), projectId, OrderTypeEnum.PROJECT.getValue());
                if (stock == null || stock.getCurrentNum() < 1) {
                    throw new CustomException("当前分配项目库存不足！");
                }
                StudentProject studentProject = new StudentProject();
                studentProject.setStudentId(id);
                studentProject.setProjectId(projectId);
                studentProjects.add(studentProject);
                stock.setCurrentNum(stock.getCurrentNum() - 1);
                trainingOrganizationStockMapper.updateByPrimaryKeySelective(stock);
            }
            if (studentProjects != null && studentProjects.size() > 0) {
                studentProjectMapper.batchInsert(studentProjects);
            }
        }

    }

    /**
     * 机构给学员分配课程
     *
     * @param dto
     * @param id
     */
    private void saveStudentCourse(StudentDto dto, Integer id) {
        if (dto.getCourseIds().size() > 0) {
            List<StudentCourse> studentCourses = new ArrayList<>();
            for (Integer courseId : dto.getProjectIds()) {
                TrainingOrganizationStock stock = trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(dto.getTrainingOrganizationId(), courseId, OrderTypeEnum.PROJECT.getValue());
                if (stock == null || stock.getCurrentNum() < 1) {
                    throw new CustomException("当前分配课程库存不足！");
                }
                StudentCourse studentCourse = new StudentCourse();
                studentCourse.setStudentId(id);
                studentCourse.setCourseId(courseId);
                studentCourses.add(studentCourse);
                stock.setCurrentNum(stock.getCurrentNum() - 1);
                trainingOrganizationStockMapper.updateByPrimaryKeySelective(stock);
            }
            if (studentCourses != null && studentCourses.size() > 0) {
                studentCourseMapper.batchInsert(studentCourses);
            }
        }

    }

    /**
     * 机构给学员分配课程包
     *
     * @param dto
     * @param id
     */
    private void saveStudentCoursePackage(StudentDto dto, Integer id) {
        if (dto.getCourseIds().size() > 0) {
            List<StudentCoursePackage> studentCoursePackages = new ArrayList<>();
            for (Integer packageId : dto.getProjectIds()) {
                TrainingOrganizationStock stock = trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(dto.getTrainingOrganizationId(), packageId, OrderTypeEnum.PROJECT.getValue());
                if (stock == null || stock.getCurrentNum() < 1) {
                    throw new CustomException("当前分配课程包库存不足！");
                }
                StudentCoursePackage studentCoursePackage = new StudentCoursePackage();
                studentCoursePackage.setStudentId(id);
                studentCoursePackage.setPackageId(packageId);
                studentCoursePackages.add(studentCoursePackage);
                stock.setCurrentNum(stock.getCurrentNum() - 1);
                trainingOrganizationStockMapper.updateByPrimaryKeySelective(stock);
            }
            if (studentCoursePackages != null && studentCoursePackages.size() > 0) {
                studentCoursePackageMapper.batchInsert(studentCoursePackages);
            }
        }

    }


    /**
     * 通过机构信息生成相关账号
     *
     * @param student
     * @return
     */
    private SysUserDto generateUser(Student student) {
        SysUserDto user = new SysUserDto();
        user.setUsername(student.getTel());
        user.setName(student.getName());
        user.setChannelCode(student.getChannelCode());
        user.setMobile(student.getTel());
        user.setEmail(student.getEmail());
        user.setUserType(UserTypeEnum.STUDENT.getValue());
        user.setChannelCode(student.getChannelCode());
        user.setInviter(student.getChannelCode());
        //user.setPassword(student.getTel());
        user.setPassword(student.getIdCard().substring(student.getIdCard().length() - 6, student.getIdCard().length()));
        user.setIdCard(student.getIdCard());
        user.setStatus(BaseStatusEnum.VALID.getValue());

        return user;
    }

    /**
     * 更新
     *
     * @param dto
     * @return
     */
    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public int update(StudentDto dto) {
        if (dto.getId() == null) {
            throw new CustomException("参数id不能为空");
        }
        Student checkStudent = selectByTelOrIdCard(dto.getTel(), dto.getIdCard());
        if (checkStudent != null && !checkStudent.getId().equals(dto.getId())) {
            throw new CustomException("当前手机号或身份证号已存在");
        }
        saveStudentProject(dto, dto.getId());
        saveStudentCourse(dto, dto.getId());
        saveStudentCoursePackage(dto, dto.getId());
        Student student = studentMapper.selectByPrimaryKey(dto.getId());

        //更新相关用户
        SysUser user = sysUserService.selectByUsername(student.getTel());
        if (dto.getTel() != null && !student.getTel().equals(dto.getTel())) {
            smsRecordService.checkCode(dto.getTel(), dto.getValidateCode());
            if (!passwordEncoder.matches(dto.getPassword(), user.getPassword())) {
                throw new CustomException("密码不正确！");
            }
        }
        user.setUsername(dto.getTel());
        user.setMobile(dto.getTel());
        user.setIdCard(dto.getIdCard());
        user.setName(dto.getName());
        sysUserService.update(user);
        BeanUtils.copyProperties(dto, student);
        return studentMapper.updateByPrimaryKeySelective(student);
    }

    public int judgeTel( Integer id ,  String tel) {
        Student checkStudent = selectByTelOrIdCard(tel, null);
        if (checkStudent != null && !checkStudent.getId().equals(id)) {
            throw new CustomException("当前手机号或身份证号已存在");
        }
        return 0;
    }

    /**
     * 更新状态
     *
     * @param id
     * @return
     */
    public int updateStatus(Integer id) {
        Student student = studentMapper.selectByPrimaryKey(id);
        if (student == null) {
            throw new CustomException("当前学生不存在");
        }
        SysUser user = sysUserService.selectByUsername(student.getTel());
        if (student.getStatus().equals(BaseStatusEnum.VALID.getValue())) {
            student.setStatus(BaseStatusEnum.INVALID.getValue());
        } else {
            student.setStatus(BaseStatusEnum.VALID.getValue());
        }
        sysUserService.updateStatus(user.getId());
        return studentMapper.updateByPrimaryKeySelective(student);
    }


    /**
     * 删除
     *
     * @param id
     * @return
     */
    public int delete(Integer id) {
        return studentMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public Student selectById(Integer id) {
        Student student = studentMapper.selectByPrimaryKey(id);
        List<Integer> courseIds = myResourceService.selectCourseIdsByStudentId(id);
        if (courseIds.size() > 0) {
            List<Course> list = myResourceService.selectByCourseNameAndCourseIds("",null, courseIds);
            student.setCourses(list);
        }
        List<OnlineVo> onlineList = studentExamMapper.selectByStudentId(id);
        student.setOnlineList(onlineList);

        // List<OfflineVo> offlineList = new ArrayList<>();
        StudentAchievementDto dto = new StudentAchievementDto();
        dto.setStudentId(id);
        List<StudentAchievement> offlineList = studentAchievementMapper.selectMyAchievement(dto);
        student.setOfflineList(offlineList);
        return student;
    }

    /**
     * 重置学员密码
     *
     * @param account
     * @param pwd
     * @return
     */
    public int resetStudentPwd(String account, String pwd) {
        return sysUserService.resetPwdByAccount(account, pwd);
    }

    /**
     * 根据参数查询学员列表
     *
     * @param name                   姓名
     * @param idCard                 身份证
     * @param tel                    电话
     * @param status                 状态
     * @param projectId              项目id
     * @param trainingOrganizationId 机构id
     * @return
     */
    public List<Student> selectByParams(String name, String idCard, String tel, Integer status, Integer projectId, Integer trainingOrganizationId) {
        return studentMapper.selectByParams(name, idCard, tel, status, projectId, trainingOrganizationId);
    }

    /**
     * 根据参数查询学员列表
     *
     * @param name                   姓名
     * @param idCard                 身份证
     * @param tel                    电话
     * @param status                 状态
     * @param projectId              项目id
     * @param trainingOrganizationId 机构id
     * @return
     */
    public List<Student> selectByParam(String name, String idCard, String tel, Integer status, Integer projectId, Integer trainingOrganizationId) {
        return studentMapper.selectByParam(name, idCard, tel, status, projectId, trainingOrganizationId);
    }
}
